package VideoProcessing;

import java.awt.Dimension;
import java.awt.image.WritableRaster;
import java.util.Arrays;

import javax.media.format.VideoFormat;
import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;

public class Smoothing extends RgbVideoEffect {
	private static final int FILTER_SIZE = 3;

	@Override
	protected boolean processRGB(byte[] bin, byte[] bout, VideoFormat format) {
		byte[] tmp = new byte[bin.length];
		int[] med = new int[FILTER_SIZE * FILTER_SIZE];
		Dimension size = format.getSize();
		for (int y = 0; y < size.height; y++) {
			for (int x = 0; x < size.width; x++) {
					int tx, ty, n = 0;
					for (int ox = -FILTER_SIZE / 2; ox <= FILTER_SIZE / 2; ox++) {
						for (int oy = -FILTER_SIZE / 2; oy <= FILTER_SIZE / 2; oy++) {
							tx = x + ox;
							ty = y + oy;
							if (inBoundry(tx, size.width)
									&& inBoundry(ty, size.height)) {
								med[n++] = byte2Int(bin[(ty * size.width + tx)]);
							} else {
								med[n++] = 0;
							}
						}
					}
					tmp[(y * size.width + x)] = findMedian(med);
				}
		}
		System.arraycopy(tmp, 0, bout, 0, tmp.length);
		return true;
	}

	private byte findMedian(int[] med) {
		Arrays.sort(med);
		return (byte) med[med.length / 2];
	}

	private boolean inBoundry(int co, int max) {
		return 0 <= co && co < max;
	}

	@Override
	public String getName() {
		return "Smoothing";
	}
	protected void updateImage(byte[] bout, VideoFormat vformat) {
		synchronized (displayImage) {
			// // Copy pixels to image
			WritableRaster rast = displayImage.getRaster();
			int[] pixel = new int[] { 0, 0, 0, 255 };
			int p = 0;
			for (int y = vformat.getSize().height - 1; y >= 0; y--) {
				for (int x = 0; x < vformat.getSize().width; x++) {
					pixel[0] = pixel[1] = pixel[2] = bout[p++];
					rast.setPixel(x, y, pixel);
				}
			}
		}
	}
}
